#include "stdafx.h"

#include "log/message.hpp"
#include "stdlib/exception.hpp"
using namespace JHCPP::stdlib::jhException;
#include "filesys/process.hpp"
using namespace JHCPP::filesys;
#include "thread/thread.hpp"
using namespace JHCPP::thread;
#include <algorithm>

namespace JHCPP
{
	namespace log
	{
		CMessage::CMessage()
		: m_prio(PRIO_FATAL), 
		m_tid(0), 
		m_pid(0),
		m_file(0),
		m_line(0),
		m_pMap(0) 
		{
			init();
		}

		CMessage::CMessage(const std::string& source, const std::string& text, Priority prio)
		: m_source(source), 
		m_text(text), 
		m_prio(prio), 
		m_tid(0),
		m_pid(0),
		m_file(0),
		m_line(0),
		m_pMap(0) 
		{
			init();
		}

		CMessage::CMessage(const std::string& source, const std::string& text, Priority prio, const char* file, int line)
		: m_source(source), 
		m_text(text), 
		m_prio(prio), 
		m_tid(0),
		m_pid(0),
		m_file(file),
		m_line(line),
		m_pMap(0) 
		{
			init();
		}

		CMessage::CMessage(const CMessage& msg)
		: m_source(msg.m_source),
		m_text(msg.m_text),
		m_prio(msg.m_prio),
		m_time(msg.m_time),
		m_tid(msg.m_tid),
		m_thread(msg.m_thread),
		m_pid(msg.m_pid),
		m_file(msg.m_file),
		m_line(msg.m_line)
		{
			if (msg.m_pMap)
				m_pMap = new StringMap(*msg.m_pMap);
			else
				m_pMap = 0;
		}

		CMessage::CMessage(const CMessage& msg, const std::string& text)
		: m_source(msg.m_source),
		m_text(text),
		m_prio(msg.m_prio),
		m_time(msg.m_time),
		m_tid(msg.m_tid),
		m_thread(msg.m_thread),
		m_pid(msg.m_pid),
		m_file(msg.m_file),
		m_line(msg.m_line)
		{
			if (msg.m_pMap)
				m_pMap = new StringMap(*msg.m_pMap);
			else
				m_pMap = 0;
		}

		CMessage::~CMessage()
		{
			delete m_pMap;
		}

		void CMessage::init()
		{
			m_pid = CProcess::id();
	
			CThread* pThread = CThread::current();
			if (pThread)
			{
				m_tid    = pThread->id();
				m_thread = pThread->name();
			}
		}

		CMessage& CMessage::operator = (const CMessage& msg)
		{
			if (&msg != this)
			{
				CMessage tmp(msg);
				swap(tmp);
			}
			return *this;
		}

		void CMessage::swap(CMessage& msg)
		{
			using std::swap;
			swap(m_source, msg.m_source);
			swap(m_text, msg.m_text);
			swap(m_prio, msg.m_prio);
			swap(m_time, msg.m_time);
			swap(m_tid, msg.m_tid);
			swap(m_thread, msg.m_thread);
			swap(m_pid, msg.m_pid);
			swap(m_file, msg.m_file);
			swap(m_line, msg.m_line);
			swap(m_pMap, msg.m_pMap);
		}

		void CMessage::setSource(const std::string& src)
		{
			m_source = src;
		}

		const std::string& CMessage::getSource() const
		{
			return m_source;
		}

		void CMessage::setText(const std::string& text)
		{
			m_text = text;
		}

		const std::string& CMessage::getText() const
		{
			return m_text;
		}

		void CMessage::setPriority(Priority prio)
		{
			m_prio = prio;
		}

		CMessage::Priority CMessage::getPriority() const
		{
			return m_prio;
		}

		void CMessage::setTime(const CTimeStamp& t)
		{
			m_time = t;
		}

		const CTimeStamp& CMessage::getTime() const
		{
			return m_time;
		}

		void CMessage::setThread(const std::string& thread)
		{
			m_thread = thread;
		}

		const std::string& CMessage::getThread() const
		{
			return m_thread;
		}

		void CMessage::setTid(long tid)
		{
			m_tid = tid;
		}

		long CMessage::getTid() const
		{
			return m_tid;
		}

		void CMessage::setPid(long pid)
		{
			m_pid = pid;
		}

		long CMessage::getPid() const
		{
			return m_pid;
		}

		void CMessage::setSourceFile(const char* file)
		{
			m_file = file;
		}

		const char* CMessage::getSourceFile() const
		{
			return m_file;
		}

		void CMessage::setSourceLine(int line)
		{
			m_line = line;
		}

		int CMessage::getSourceLine() const
		{
			return m_line;
		}

		const std::string& CMessage::operator [] (const std::string& param) const
		{
			if (m_pMap)
				return (*m_pMap)[param];
			else
				throw NotFoundException();
		}

		std::string& CMessage::operator [] (const std::string& param)
		{
			if (!m_pMap)
				m_pMap = new StringMap;
			return (*m_pMap)[param];
		}
	}//end of namespace log
}//end of namespace JHCPP
